package jmeterBusiness;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import impl.TestServerBusinessImpl;
import models.GetRequestInputStream;
import models.MyConfig;
import models.ReturnJson;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.Iterator;
import java.util.Objects;

/**
 * Created by yangxianming on 2019/9/23.
 * 对jmx文件的用户自定义模块做展示和编辑
 */
public class JmxManager implements TestServerBusinessImpl {
    @Override
    public String doIt(HttpServletRequest request, MyConfig myConfig) {
        //初始化返回对象，读取请求数据
        ReturnJson returnJson = new ReturnJson();
        JSONObject apiJson = GetRequestInputStream.getJson(request);
        String action = apiJson.getString("action");
        String projectName = apiJson.getString("projectName");
        String jmxFileName = apiJson.getString("jmxFileName");

        //获取系统名字和文件路径
        String splitMark = myConfig.getSplitMark("splitMark");
        String appPath = myConfig.getPropertiesConfig().getProperties().getProperty("appPath");
        String jmxPath = appPath + splitMark + "jmeterScript" + splitMark + projectName + splitMark + jmxFileName;

        try {
            //读取jmx文件
            File f = new File(jmxPath);
            SAXReader reader = new SAXReader();
            Document doc = reader.read(f);
            Element root = doc.getRootElement();
            Element arguments = getElement("Arguments", root);

            if (Objects.equals(arguments, null)){
                returnJson.setApiStatus(0);
                returnJson.setErrorMsg("需要jmx中的‘用户定义的变量’才能完成在线编辑和查看");
                return returnJson.toString();
            }

            //展示
            if (Objects.equals(action, "show")){
                returnJson.setApiStatus(1);
                returnJson.setResult(showKV(arguments));
                return returnJson.toString();
            }

            //编辑
            if (Objects.equals(action, "edit")){
                JSONArray editInfo = apiJson.getJSONArray("editInfo");
                for (Object one: editInfo){
                    JSONObject oneInfo = (JSONObject)one;
                    changeV(arguments, oneInfo.getString("k"), oneInfo.getString("v"));
                }
//                Writer fileWriter = new FileWriter(new File(jmxPath));
                //dom4j设置字符格式只是把文件头设置成utf8，而且用FileWriter写文件默认格式ANSI
                //防止dom4j输出文件不是utf8的方式是使用FileOutputStream
                FileOutputStream fileOutputStream = new FileOutputStream(new File(jmxPath));
                OutputFormat xmlFormat = OutputFormat.createPrettyPrint();
                xmlFormat.setEncoding("UTF-8");
                XMLWriter writer = new XMLWriter(fileOutputStream, xmlFormat);
                writer.write(doc);
                writer.flush();
                writer.close();

                returnJson.setApiStatus(1);
                returnJson.setResult("ok");
                return returnJson.toString();
            }

        }catch (IOException ioe){
            ioe.printStackTrace();
            returnJson.setApiStatus(0);
            returnJson.setErrorMsg("打开文件似乎出现了一点小问题");
        }catch (DocumentException de){
            de.printStackTrace();
            returnJson.setApiStatus(0);
            returnJson.setErrorMsg("打开文件似乎出现了一点小问题");
        }

        return returnJson.toString();
    }

    //得到arguments元素
    private Element getElement(String tarElementName, Element root){
        Element backElement = null;
        for (Iterator it1 = root.elementIterator(); it1.hasNext();){
            Element e = (Element)it1.next();
            if (Objects.equals(tarElementName, e.getName()) && Objects.equals(e.attribute("enabled").getValue(), "true")){
//            if (Objects.equals(tarElementName, e.getName())){
                return e;
            }
            backElement = getElement(tarElementName, root.element(e.getName()));
        }
        return backElement;
    }

    private void changeV(Element ee, String k, String v){
        Element e = ee.element("collectionProp");
        for (Iterator it2 = e.elementIterator(); it2.hasNext();){
            Element e1 = (Element)it2.next();
            String tarName = e1.attribute("name").getValue();
//            System.out.println("elementProp name:" + e1.attribute("name").getValue());
            if (!Objects.equals(tarName, k)){
                continue;   //如果不是目标元素就跳过
            }
            //得到elementProp下的stringProp节点组
            for (Iterator it3 = e1.elementIterator(); it3.hasNext();){
                Element e2 = (Element)it3.next();
                String name = e2.attribute("name").getValue();
                if (Objects.equals(name, "Argument.value")){
//                    System.out.println("v:" + e2.getText());
                    e2.setText(v);
                }
            }
        }
    }

    private JSONArray showKV(Element ee){
        Element e = ee.element("collectionProp");
        JSONArray jsonArray = new JSONArray();
        for (Iterator it2 = e.elementIterator(); it2.hasNext();){
            Element e1 = (Element)it2.next();
//            System.out.println("elementProp name:" + e1.attribute("name").getValue());
            //得到elementProp下的stringProp节点组
            JSONObject jsonObject = new JSONObject();
            for (Iterator it3 = e1.elementIterator(); it3.hasNext();){
                Element e2 = (Element)it3.next();
                String name = e2.attribute("name").getValue();
                if (Objects.equals(name, "Argument.name")){
//                    System.out.println("k:" + e2.getText());
                    jsonObject.put("k", e2.getText());
                }
                if (Objects.equals(name, "Argument.value")){
//                    System.out.println("v:" + e2.getText());
                    jsonObject.put("v", e2.getText());
                }
            }
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }
}
